hhkb
웹 개발

블로그_11_대규모 기능 개선하기

작성자 : Heehyeon Yoo|2025-12-26
# Blog# Refactoring# Performance# Security# Next.js

구조 정리의 날

기능이 많아지고 복잡해지면서 체감 성능, 보안 리스크, 경로 일관성 같은 문제가 슬슬 보였다.
이번에는 기능을 새로 붙이기보다 기존 기능을 안정화하고 구조를 정리하는 데 집중했다.
오늘 손본 항목들을 그대로 기록해 둔다.

1. 빌드 에러 대응: middleware matcher 정적화

Next.js 16(Turbopack)에서 middleware.tsmatcher는 정적 문자열이어야 한다.
기존에는 관리자 경로를 기준으로 matcher 배열을 동적으로 만들고 있었고, 이게 컴파일 타임에 해석되지 않아서 빌드가 막혔다.

해결은 간단했다.

  • matcher는 정적 패턴으로 고정
  • 실제 분기 로직은 미들웨어 내부에서 처리

덕분에 빌드는 통과하고, 런타임 동작도 유지된다.

2. 관리자 경로 정리 + 접근 제어 통일

관리자 경로가 여러 군데 흩어져 있었다.
/vault-admin을 기본값으로 두되 환경 변수로 바꿀 수 있는 구조라, 링크를 손보는 데만 시간이 걸렸다.

그래서 관리자 경로를 하나의 모듈로 모았다.

  • getAdminPath, buildAdminHref로 경로 생성 통일
  • Sidebar, FileTree, edit/new 페이지 모두 동일 경로 사용
  • next.config에서 rewrite를 걸어 경로 변경 시도에도 내부 라우트는 안정적으로 유지

그리고 설정 기능은 관리자만 가능하도록 명확하게 막았다.
추천 학습/뉴스 피드 설정 모달은

  • 비관리자일 때 버튼 자체 비활성화
  • 모달 내부 조작/저장도 차단
    이렇게 UI와 동작 모두를 잠갔다.

3. 링크 경로 정합성: 슬러그/포스트 경로 통합

학습 트리나 추천 영역에서 링크가 간헐적으로 깨지는 문제가 있었다.
슬러그가 notes/...인지, 마지막 조각인지, 디코딩이 필요한지에 따라 경로가 섞여 있었기 때문이다.

그래서 모든 포스트의 슬러그를 인덱스로 만들어
어떤 입력이 와도 정확한 실제 경로로 매핑하도록 했다.

  • 전체 포스트 기반 postSlugIndex 생성
  • 디코딩된 슬러그도 함께 매핑
  • resolvePostHref로 최종 경로 확정

이제 Study Tree, 추천 카드, 그래프 링크가 모두 동일한 규칙으로 움직인다.

4. JSON 데이터 로딩 구조 정리

트리 패널의 데이터나 학습 브리핑 데이터는 JSON 기반의 정적 데이터다.
이걸 클라이언트에서 직접 import하면 번들에 그대로 포함되어 초기 로딩 비용이 커진다.
그래서 구조를 다음처럼 바꿨다.

  • 서버 컴포넌트에서 JSON 로드
  • 클라이언트에는 필요한 데이터만 props로 전달
  • 타입은 knowledge-graph-types로 통일

결과적으로 번들이 줄고, 데이터 소스도 한 군데로 정리됐다.

5. 날짜/타임존 안정화: 기여 그래프 개선

기여 그래프에서 날짜가 하루씩 밀리는 현상이 있었다.
UTC 변환과 로컬 타임존이 섞이면서 생기는 전형적인 문제다.

로컬 기준 날짜 유틸을 만들어 정리했다.

  • 입력 파싱과 날짜 키 생성 로직 통일
  • 기여 그래프는 항상 로컬 날짜 키 기준으로 표시
  • 데이터가 없던 연도도 자동으로 선택 가능하도록 개선

그래프의 날짜가 이제 실제 작성일과 맞게 표시된다.

6. RSS 수집 보안 보강

뉴스 피드 기능은 외부 URL을 받아 서버에서 fetch한다.
이건 SSRF의 전형적인 진입점이라 방어가 필수라고 배웠다.

방어 정책을 명확히 넣었다.

  • http/https 외 프로토콜 차단
  • username:password@host 형태 차단
  • localhost, private IP, 내부 도메인 차단
  • 리다이렉트 횟수 제한 + 리다이렉트마다 재검증
  • 필요하면 RSS_ALLOWED_HOSTS allowlist로 범위 제한

보안 리스크는 줄이고, 캐시는 revalidate로 안정성도 확보했다.

7. 이미지 선택 패널 성능 개선

이미지 선택 패널은 열 때마다 폴더를 새로 읽고 있었다.
편집 모드에선 괜찮았지만, 일반 사용에선 불필요한 비용인데 쓰고 있었다.

기본 동작을 캐시 기반으로 바꾸고,
필요할 때만 강제로 새로고침할 수 있게 했다.

  • 기본: 캐시 사용
  • 새로고침 버튼: fresh 파라미터로 캐시 우회

체감 성능이 좋아지고, 편집 흐름도 끊기지 않는다.

8. 의존성/불필요한 코드 정리

개발하다가 멈췄거나, 데모 기능이나 목업 등 쓰지 않는 컴포넌트와 스크립트, 의존성을 정리했다.

  • 사용되지 않는 컴포넌트 제거
  • 테스트용 스크립트, 임시 로그 문서 제거
  • 사용하지 않는 에디터 패키지(@mdxeditor, @milkdown)와 date-fns 정리

9. 코드 재사용성 정리

스킬 트리에서 링크에 문제가 좀 있었는데 수정하려 했더니 복잡해졌다.
3. 링크 경로 정합성의 내용이다.

경로, 날짜, 그래프 타입 같은 기본 로직이 흩어져 있으면 이후 수정 비용이 커진다.
그래서 공통 유틸로 모았다.

  • 관리자 경로: admin-path
  • 포스트 경로: post-path
  • 날짜 처리: date-utils
  • 그래프 타입: knowledge-graph-types

수정 지점이 한 곳으로 모이면서 유지보수성이 확실히 올라갔다.

오늘은 기능을 더하는 대신, 기능이 안정적으로 돌아가게 만드는 작업에 집중했다.

  • 빌드 에러 제거 + 라우팅 정합성 확보
  • 관리자 경로/권한 흐름 통일
  • 포스트 링크 깨짐 문제 해소
  • 지식 그래프/브리핑 데이터 로딩 최적화
  • 날짜/타임존 정합성 개선
  • RSS 보안/성능 보강
  • 이미지 패널 캐시 전략 정리
  • 불필요한 코드/의존성 제거 + 재사용성 강화

다음으로 뭐 붙일 때는 좀 더 계획하고 생각하고 붙여보자....

hhkb